package com.project.demo.game;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.project.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.logging.Handler;

/**
 * Created with IntelliJ IDEA.
 * Description:匹配器，完成匹配功能
 * User:DELL
 * Time:22:01
 */
@Component
public class Matcher {
    //创建三个队列
    private Queue<User> normalQueue = new LinkedList<>();
    private Queue<User> highQueue = new LinkedList<>();
    private Queue<User> veryHighQueue = new LinkedList<>();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private RoomManage roomManage;

    //把玩家放到匹配队列中
    public void add(User user){
        if (user.getScore()<2000){
            synchronized (normalQueue) {
                normalQueue.offer(user);
                normalQueue.notify();
            }
            System.out.println("把玩家 " + user.getUsername() + "加入到了 normalQueue 中！");
        }else if (user.getScore() >= 2000 && user.getScore() < 3000){
            synchronized (highQueue) {
                highQueue.offer(user);
                highQueue.notify();
            }
            System.out.println("把玩家 " + user.getUsername() + "加入到了 highQueue 中！");
        }else {
            synchronized (veryHighQueue) {
                veryHighQueue.offer(user);
                veryHighQueue.notify();
            }
            System.out.println("把玩家 " + user.getUsername() + "加入到了 veryHighQueue 中！");
        }
    }

    //玩家点击停止匹配，玩家从匹配队列中删除
    public  void remove(User user){
        if (user.getScore()<2000){
            synchronized (normalQueue) {
                normalQueue.remove(user);
            }
            System.out.println("把玩家 " + user.getUsername() + "移除了 normalQueue 中！");
        }else if (user.getScore() >= 2000 && user.getScore() < 3000){
            synchronized (highQueue) {
                highQueue.remove(user);
                System.out.println("把玩家 " + user.getUsername() + "移除了 highQueue 中！");
            }
        }else {
            synchronized (veryHighQueue) {
                veryHighQueue.remove(user);
                System.out.println("把玩家 " + user.getUsername() + "移除了 veryHighQueue 中！");
            }
        }
    }

    public Matcher(){
        //创建三个线程，分别对匹配队列进行操作
        Thread t1 = new Thread(){
            @Override
            public void run() {
                //扫描normalQueue
                while (true){
                    HandlerMatch(normalQueue);
                }
            }
        };
        t1.start();

        Thread t2 = new Thread(){
            @Override
            public void run() {
                while (true){
                    HandlerMatch(highQueue);
                }
            }
        };
        t2.start();

        Thread t3 = new Thread(){
            @Override
            public void run() {
                while (true){
                    HandlerMatch(veryHighQueue);
                }
            }
        };
        t3.start();
    }

    private void HandlerMatch(Queue<User> matchQueue) {
        synchronized (matchQueue) {
            try {
                //监测对列中元素个数是否为2
                while (matchQueue.size() < 2) {
                    matchQueue.wait();
                }
                //尝试从对列中去除两个玩家
                User player1 = matchQueue.poll();
                User player2 = matchQueue.poll();
                System.out.println("匹配出两个玩家：" + player1.getUsername() + " , " + player2.getUsername());
                //获取websocket会话-告诉玩家排到了
                WebSocketSession session1 = onlineUserManager.getFromGameHall(player1.getUserId());
                WebSocketSession session2 = onlineUserManager.getFromGameHall(player2.getUserId());
                if (session1 == null) {
                    //玩家1不在线，玩家2重新放回到匹配中
                    matchQueue.offer(player2);
                    return;
                }

                if (session2 == null) {
                    //玩家二不在线
                    matchQueue.offer(player1);
                    return;
                }
                //排到了同一个人
                if (session1 == session2) {
                    //把其中一个玩家放回到匹配队列中
                    matchQueue.offer(player1);
                    return;
                }

                //把这两个玩家放入到一个游戏房间中
                Room room = new Room();
                roomManage.add(room, player1.getUserId(), player2.getUserId());
                //给玩家反馈信息
                MatchResponse response1 = new MatchResponse();
                response1.setOk(true);
                response1.setMessage("matchMessage");
                String json1 = objectMapper.writeValueAsString(response1);
                session1.sendMessage(new TextMessage(json1));

                MatchResponse response2 = new MatchResponse();
                response2.setOk(true);
                response2.setMessage("matchMessage");
                String json2 = objectMapper.writeValueAsString(response2);
                session2.sendMessage(new TextMessage(json2));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
